package com.lemon.redis.config;

import com.lemon.redis.properties.RedisConfigProperties;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;

import java.time.Duration;

/**
 * @author 李猛
 * @datetime 2024/2/15 23:24
 * @description 类对象
 */
@AutoConfigureAfter({RedisAutoConfiguration.class}) // 之后配置链接工厂
@EnableConfigurationProperties({RedisConfigProperties.class}) // 依赖配置文件
@ConditionalOnExpression("true")
public class LettuceConnectionFactoryConfiguration {

    /**
     * 配置连接池信息
     * 容器在缺失 RedisConnectionFactory 配置的时候, 会兜底注入 JedisConnectionFactory
     *
     * @param properties
     * @return
     */
    @Bean
    @Primary
    public LettuceConnectionFactory lettuceConnectionFactory(final RedisConfigProperties properties) {
        // 基础配置
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setDatabase(properties.getDatabase());
        redisStandaloneConfiguration.setHostName(properties.getHost());
        redisStandaloneConfiguration.setPort(properties.getPort());
        redisStandaloneConfiguration.setPassword(RedisPassword.of(properties.getPassword()));
        // 连接池配置
        LettucePoolingClientConfiguration lettuceClientConfiguration = LettucePoolingClientConfiguration
                .builder()
                .commandTimeout(Duration.ofMillis(properties.getTimeout()))
                .poolConfig(getPoolConfig(properties)).build();

        // 根据配置和客户端配置创建连接
        LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration, lettuceClientConfiguration);
        lettuceConnectionFactory.afterPropertiesSet();
        return lettuceConnectionFactory;
    }

    /**
     * 获取连接池配置
     *
     * @param properties
     * @return
     */
    private GenericObjectPoolConfig getPoolConfig(final RedisConfigProperties properties) {
        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxIdle(properties.getMaxIdle());
        genericObjectPoolConfig.setMinIdle(properties.getMinIdle());
        genericObjectPoolConfig.setMaxTotal(properties.getMaxTotal());
        genericObjectPoolConfig.setMaxWaitMillis(properties.getMaxWait());
        return genericObjectPoolConfig;
    }

}
